package com.sunshine.client.factory.support;

import com.sunshine.client.bean.MethodInfo;
import com.sunshine.client.bean.ServiceInfo;
import com.sunshine.client.factory.RestHandler;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * @author Mokairui
 * @description frame-module
 * @since 2022/5/8
 */
public class WebClientRestHandler implements RestHandler {
    private WebClient client;
    
    @Override
    public void init(ServiceInfo serviceInfo) {
        this.client = WebClient.create(serviceInfo.getUrl());
    }

    @Override
    public Object invokeRest(MethodInfo methodInfo) {
        // 返回结果
        Object result = null;
        
        WebClient.RequestBodySpec requestSpec = this.client.method(methodInfo.getMethod()) // 请求方法
                .uri(methodInfo.getUrl()) // 请求 url
                .accept(MediaType.APPLICATION_JSON);
        
        WebClient.ResponseSpec responseSpec = null;
        
        // 判断是否带了 body
        if (methodInfo.getBody() != null) {
            // 发出请求
            responseSpec = requestSpec.body(methodInfo.getBody(), methodInfo.getBodyElementType()).retrieve();
        } else {
            responseSpec = requestSpec.retrieve();
        }
        
        // 处理异常
        responseSpec.onStatus(status -> status.value() == 404, 
                response -> Mono.just(new RuntimeException("Not Found")));

        // 处理请求 body
        if (methodInfo.isReturnFlux()) {
            result = responseSpec.bodyToFlux(methodInfo.getReturnElementType());
        } else {
            result = responseSpec.bodyToMono(methodInfo.getReturnElementType());
        }
        
        return result;
    }
}
